#! /usr/bin/env python
"""This module is a solver for the game FreeCell"""

import pdb

pdb.set_trace()

class StandardDeck:
    """This class is used to keep track of the cards in the deck"""
    def __init__(self):
        """The value of an individual card is comprised of it's suit and card
        value (e.g. ace, queen, king) summed (e.g. nine of diamonds would be
        109) where the hundreds place digit is the suit and the tens and ones
        place represents the value.
        ## card values
        # ace  1
        # two  2
        # three  3
        # four  4
        # five  5
        # six  6
        # seven  7
        # eight  8
        # nine  9
        # ten  10
        # jack  11
        # queen  12
        # king  13

        ## suits
        # diamond  100
        # heart  200
        # club  300
        # spade  400

        """
        self.cards = []

        for suit in range(100, 500, 100):
            for value in range(1, 14):
                #print(str.join("", ["hello ", str(suit+value)]))
                self.cards.append(suit+value)

        print(self.cards)

    def get_suit(self, value):
        """Returns the suit of a card"""
        if 100 <= value < 200:
            return 1
        elif 200 <= value < 300:
            return 2
        elif 300 <= value < 400:
            return 3
        elif 400 <= value < 500:
            return 4
        else:
            return 0


class Tableau:
    """This class represents the 8 tableaus that will be populated with cards
    from the StandardDeck.

    """
    def __init__(self):
        """Creates the piles list that keeps track of the tableaus"""
        self.piles = []
        for pile in range(8):
            self.piles.append([])
        print(self.piles)

    def add(self, card, position):
        """The card parameter is used to refernce exactly which card is being
        added and position refers to where in the tableaus the card lies.

        """
        #print(position)
        #print(self.piles[position[0]])
        if position[1] >= len(self.piles[position[0]]):
            for placeHolder in range(len(self.piles[position[0]]), position[1]+1):
                if placeHolder == position[1]:
                    self.piles[position[0]].append(card)
                else:
                    self.piles[position[0]].append(0)
        else:
            self.piles[position[0]][position[1]] = card
        print(self.piles)
   
    def move(self, card, position):
       pass

    def read(self, file_name):
        file_object = open(file_name, "r")
        layout = file_object.read()
        file_object.close()

        for index, line in enumerate(layout.splitlines()):
            for card_value in line.split(" "):
                self.piles[index].append(int(card_value))


class Foundation:
    """This class is to keep track of which cards have been removed from the
    tableaus and cells.

    """
    def __init__(self):
        self.foundations = [[], [], [], []]

    def add(self, value):
        if 100 <= value < 200:
            self.foundations[0].append(value)
        elif 200 <= value < 300:
            self.foundations[1].append(value)
        elif 300 <= value < 400:
            self.foundations[2].append(value)
        elif 400 <= value < 500:
            self.foundations[3].append(value)


class Cell:
    """This class is to keep track of which cards are in the free cells."""
    def __init__(self):
        self.cells = ["   ", "   ", "   ", "   "]


class Solver:
    def __init__(self, standard_deck, layout, foundation):
        self.layout = layout
        self.foundations = foundation
        self.deck = standard_deck

    def solve(self):
        pass

    def get_dependency(self, value):
        self.depends.append(value)
        for pile in self.layout:
            if value in pile:
                if pile.index(value) == len(pile)-1:
                    suit = self.deck.get_suit(value)
                    if self.foundations.foundations[suit-1][len(self.\
                       foundations.foundations[suit])-1] == value-1:
                        self.foundations.add(value)
                        print(self.foundations.foundations)
                else:
                    pass

    def is_covered(self, value):
        pass


class Layout:
    def __init__(self, deck, cells, foundations, tableaus):
        self.deck = deck
        self.cells = cells
        self.foundations = foundations
        self.tableaus = tableaus

    def print_layout(self):
        layout = "[{}] [{}] [{}] [{}]".format(*self.cells.cells)
        str.join("", [layout, " [{}] [{}] [{}] [{}]\n".format(*self.foundations.foundations)])
        for index, tableau in enumerate(self.tableaus.piles):
            if index < 6:
                print(tableau)
                str.join("", [layout, "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}]\n".format(*tableau)])
            else:
                str.join("", [layout, "[{}] [{}] [{}] [{}] [{}] [{}] [{}]\n".format(*tableau)])


if __name__ == "__main__":
    deck = StandardDeck()
    tableaus = Tableau()
    foundations = Foundation()
    cells = Cell()
    layout = Layout(deck, cells, foundations, tableaus)
    command = ""
    while command != "quit":
        #print(command)
        command = raw_input("Please choose an option: add, print, \
move, solve, read, help, quit.\n--> ")

        if "add " in command[:4] and len(command) == 12 and \
int(command[4:8]) in deck.cards and 0 <= int(command[8]) <= 7 and 0 <= \
int(command[10:]) <= 18:
            """The add command uses the form: add [card, 3 digit number]
            [tableau number, 1 digit number between 0-7] 
            [row, 2 digit number between 0-18]
            e.g. add 109 1 03
            """

            print(str.join("", ["card value: ", command[4:8]]))
            print(str.join("", ["tableau: ", command[8]]))
            print(str.join("", ["row: ", command[10:]]))
            deck.cards.remove(int(command[4:8]))
            tableaus.add(int(command[4:8]), (int(command[8]), 
            int(command[10:])))
        elif "print" in command and len(command) == 5:
            layout.print_layout()
        elif "move" in command:
            pass
        elif "read" in command:
            tableaus.read("foo.txt")
            print(tableaus.piles)
        elif "solve" == command and len(command) == 5:
            pass
        elif "help" in command:
            pass
        elif "quit" == command:
            pass
        else:
            print(str.join("", ["Not a valid command: ", command]))
